package org.ala.distributed_transaction_commons.configure;

import java.util.Collection;
import java.util.HashSet;

import org.springframework.beans.MutablePropertyValues;
import org.springframework.beans.PropertyValues;
import org.springframework.context.EnvironmentAware;
import org.springframework.core.env.AbstractEnvironment;
import org.springframework.core.env.EnumerablePropertySource;
import org.springframework.core.env.Environment;
import org.springframework.core.env.PropertySource;


/**
 * 分布式事务相关配置文件解析
 * 
 * distributed_transaction:
 *   redis:
 *     host:
 *     port:
 *     password:
 *     database:
 *     timeout:
 *     poolIdle:
 *     poolMax:
 *
 * @author 骆毅(ala)
 * @date 2024年2月17日
 */
public class DistributedTransactionConfigure implements EnvironmentAware {

	
	/**
	 * key前缀
	 */
	static String KEY_PREFIX = "distributed_transaction";
	
	
	/**
	 * redis相关配置
	 */
	protected RedisConfigure redisConfigure;
	
	
	@Override
	public void setEnvironment(Environment environment) {
		//	取配置项
		String pre = KEY_PREFIX + ".";
		PropertyValues mpvs = subProperties(environment, pre);
		
		//	解析redis配置
		redisConfigure = parseRedisConfig(mpvs);
	}
	/**
	 * 解析redis配置
	 */
	protected RedisConfigure parseRedisConfig(PropertyValues mpvs) {
		RedisConfigure conf = new RedisConfigure();
		conf.setHost(mpvs.getPropertyValue(KEY_PREFIX + ".redis.host").getValue().toString());
		conf.setPort(Integer.parseInt(mpvs.getPropertyValue(KEY_PREFIX + ".redis.port").getValue().toString()));
		conf.setPassword(mpvs.getPropertyValue(KEY_PREFIX + ".redis.password").getValue().toString());
		conf.setDatabase(Integer.parseInt(mpvs.getPropertyValue(KEY_PREFIX + ".redis.database").getValue().toString()));
		conf.setTimeout(Integer.parseInt(mpvs.getPropertyValue(KEY_PREFIX + ".redis.timeout").getValue().toString()));
		conf.setPoolIdle(Integer.parseInt(mpvs.getPropertyValue(KEY_PREFIX + ".redis.poolIdle").getValue().toString()));
		conf.setPoolMax(Integer.parseInt(mpvs.getPropertyValue(KEY_PREFIX + ".redis.poolMax").getValue().toString()));
		return conf;
	}
	
	
	public RedisConfigure getRedisConfigure() {
		return redisConfigure;
	}
	public void setRedisConfigure(RedisConfigure redisConfigure) {
		this.redisConfigure = redisConfigure;
	}
	
	
	/**
	 * 获取子参数集
	 * @param env 环境上下文
	 * @param pre 参数前缀
	 * @return 子参数集
	 */
	@SuppressWarnings("rawtypes")
	public static PropertyValues subProperties(Environment env, String pre) {
		MutablePropertyValues mpvs = new MutablePropertyValues();
		Collection<String> ns = new HashSet<>();
		for (PropertySource<?> propertySource : ((AbstractEnvironment) env).getPropertySources()) {
			if (propertySource instanceof EnumerablePropertySource) {
				String[] propertyNames = ((EnumerablePropertySource) propertySource).getPropertyNames();
				for (String name : propertyNames) {
					if (name.startsWith(pre)) {
						if (!ns.add(name)) continue;
						mpvs.addPropertyValue(name, env.getProperty(name));
					}
				}
			}
		}
		return mpvs;
	}

	
	/**
	 * redis相关配置
	 */
	public static class RedisConfigure {
		protected String host;
		protected int port;
		protected String password;
		protected int database;
		protected int timeout;
		
		protected int poolIdle;
		protected int poolMax;
		public String getHost() {
			return host;
		}
		public void setHost(String host) {
			this.host = host;
		}
		public int getPort() {
			return port;
		}
		public void setPort(int port) {
			this.port = port;
		}
		public String getPassword() {
			return password;
		}
		public void setPassword(String password) {
			this.password = password;
		}
		public int getDatabase() {
			return database;
		}
		public void setDatabase(int database) {
			this.database = database;
		}
		public int getTimeout() {
			return timeout;
		}
		public void setTimeout(int timeout) {
			this.timeout = timeout;
		}
		public int getPoolIdle() {
			return poolIdle;
		}
		public void setPoolIdle(int poolIdle) {
			this.poolIdle = poolIdle;
		}
		public int getPoolMax() {
			return poolMax;
		}
		public void setPoolMax(int poolMax) {
			this.poolMax = poolMax;
		}
	}
	
	
}
